//【工具函数】/【网络通信】/【基础 Restful API 类】
import request from './request'

export default class RestApi {
  private _url: string = ''                     // 请求路径
  private _isMock: boolean = false              // 是否使用 mock 数据
  isCache: boolean = true                       // 是否缓存数据
  isAutoLoad: boolean = true                    // 请求参数变化时，是否自动加载数据

  private _listMethod: 'get' | 'post' = 'post'  // 列表数据请求方法
  private _listUrl: string = 'list'             // 列表数据请求路径

  private _parseListMethod?: (data: any) => any // 预处理列表数据的方法
  private _parseGetMethod?: (data: any) => any  // 预处理详情数据的方法


  // Api 工厂函数
  public static createRestApi(apiConfig: any): RestApi {
    const api = new RestApi()

    api._url = apiConfig.url
    api._isMock = apiConfig.isMock ?? false
    api.isCache = apiConfig.isCache ?? true
    api.isAutoLoad = apiConfig.isAutoLoad ?? true

    // 设置列表数据请求方法和路径
    api._listMethod = apiConfig.listMethod ?? 'post'
    if (api._listMethod === 'get') {
      api._listUrl = apiConfig.listUrl ?? ''
    } else {
      api._listUrl = apiConfig.listUrl ?? 'list'
    }

    // 设置预处理列表数据和详情数据的方法
    api._parseListMethod = apiConfig.parseListMethod
    api._parseGetMethod = apiConfig.parseGetMethod

    return api
  }


  // 获取数据项列表
  public async list(params?: any, mock: boolean = this._isMock): Promise<any> {
    let result: any

    // 使用 mock 数据或请求数据
    if (mock) {
      // result = await this.mockModel?.getList(params)
    } else {
      // 根据请求方法，调用对应的请求函数
      let url = this._url + (this._listUrl ? '/' + this._listUrl : '')
      if (this._listMethod === 'get') {
        result = await request.get(url, params)
      } else {
        result = await request.post(url, params)
      }

      // 如果请求失败，则返回错误信息
      if (result?.error?.value) {
        return new Promise((_, reject) => {
          reject(result?.error.value.message)
        })
      }
    }

    // 预处理列表数据
    if (this._parseListMethod) {
      return this._parseListMethod(result?.data.value)
    }
    return result?.data.value
  }


  // 获取单条数据项详情
  public async get(id: number | string, params?: any, mock: boolean = this._isMock): Promise<any> {
    let result: any

    // 使用 mock 数据或请求数据
    if (mock) {
      // result = await this.mockModel?.get(+id)
    } else {
      result = await request.get(this._url + '/' + id, params)

      if (result?.error?.value) {
        return new Promise((_, reject) => {
          reject(result?.error.value.message)
        })
      }
    }

    // 预处理详情数据
    if (this._parseGetMethod) {
      return this._parseGetMethod(result?.data.value)
    }
    return result?.data.value
  }


  // 新建数据项
  public add(data: any): Promise<any> {
    return request.post(this._url, data)
  }


  // 更新数据项
  public update(id: number | string, data: any): Promise<any> {
    return request.put(this._url + '/' + id, data)
  }


  // 删除数据项
  public delete(id: number | string): Promise<any> {
    return request.delete(this._url + '/' + id)
  }
}
